<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="description" content="coinfaces">

        <title>树莓派服务器关机</title>

    <link rel="stylesheet" href="../../theme/css/style.css">
    <link rel="stylesheet" href="../../theme/css/pygments.css">



</head>

<body>
    <div class="content">
<h1>树莓派服务器关机</h1>    <p>
        under
            <a href="../../tags/raspberrypi/">raspberrypi</a>
    </p>
    <p>
        in <a href="../../categories/tech/">tech</a>
    </p>
    <p>Published: 2016-09-11</p>

        <p>Last edit: 2019-06-08</p>

    <p>树莓派可以用作一台<a class="reference external" href="/201609/make-a-raspbian-server-zh/">廉价的家用服务器</a>，但由于它没有电源键，关机有些麻烦，一种思路是通过检测特定设备的变动来触发关机命令。</p>
<div class="section" id="usb">
<h2>拔出USB设备实现关机</h2>
<p>这种方法用设置udev规则实现：</p>
<ul>
<li><p class="first">将用来控制树莓派的USB设备接入树莓派，用<tt class="docutils literal">lsusb</tt>命令可以看它，这个命令输出的第三列应该是设备的生产商（VENDOR）和型号（MODEL）的ID，用冒号隔开</p>
</li>
<li><p class="first">用<tt class="docutils literal">udevadm monitor <span class="pre">--udev</span> <span class="pre">--property</span></tt>命令打开监控，拔出该USB设备，在输出中寻找ID_VENDOR_ID和ID_MODEL_ID，应该和<tt class="docutils literal">lsusb</tt>的输出一致</p>
</li>
<li><p class="first">创建/etc/udev/rules.d/00-auto_shutdown.rules文件，其内容如下：</p>
<pre class="literal-block">
ACTION==&quot;remove&quot;, ENV{ID_VENDOR_ID}==&quot;0bda&quot;, ENV{ID_MODEL_ID}==&quot;8176&quot;, RUN+=&quot;/sbin/shutdown -h now&quot;
</pre>
<p>记得将0bda和8176换成真实的设备ID</p>
</li>
<li><p class="first">用<tt class="docutils literal">udevadm control <span class="pre">--reload-rules</span></tt>载入新规则</p>
</li>
<li><p class="first">接上显示器后拔出该USB设备，确认是否设置成功</p>
</li>
</ul>
<p>以上内容来自于网上的<a class="reference external" href="http://raspberrypi.stackexchange.com/a/4722">这个回答</a></p>
</div>
<div class="section" id="id4">
<h2>断开网络实现关机</h2>
<p>移除USB设备关闭树莓派的方法有一个弱点，如果USB设备是存储设备，就不能在树莓派上为它分区，我用parted删除一个分区后，树莓派就自动关机了，并且同一个生产商的所有这种型号的设备都不能分区。</p>
<p>于是想到用断开网络的方式关闭树莓派，这个树莓派主要提供web服务，没有网络就没必要开着了。<a class="reference external" href="http://raspberrypi.stackexchange.com/a/22822">一种方法</a>是在“/etc/network/interfaces”配置文件中eth0设备的配置下添加<tt class="docutils literal"><span class="pre">post-down</span> /sbin/poweroff</tt>，同时也要打开ifplugd服务，拔掉网线后，ifplugd会在若干秒后（这个时间可以用<tt class="docutils literal"><span class="pre">dpkg-reconfigure</span> ifplugd</tt>指定）运行<tt class="docutils literal">ifdown</tt>命令，<tt class="docutils literal">ifdown</tt>命令便会在关闭eth0设备后运行<tt class="docutils literal">poweroff</tt>关闭树莓派。</p>
<p>上面的方法能起作用，但有一个小问题，树莓派重启（运行级别6）的时候也会运行<tt class="docutils literal">ifdown</tt>命令，并最终执行<tt class="docutils literal">poweroff</tt>，可能是这个原因导致系统死锁。解决方式是由ifplugd来执行关机脚本，ifplugd在网络设备断开时，会依次执行“/etc/ifplugd/action.d/”下的脚本，把关机脚本命名成“/etc/ifplugd/action.d/00_post_down”，内容如下：</p>
<div class="highlight"><pre><span></span><span class="ch">#!/bin/bash</span>

<span class="o">[</span> <span class="s2">&quot;</span><span class="nv">$1</span><span class="s2">&quot;</span> <span class="o">=</span> eth0 -a <span class="s2">&quot;</span><span class="nv">$2</span><span class="s2">&quot;</span> <span class="o">=</span> down <span class="o">]</span> <span class="o">&amp;&amp;</span> /sbin/poweroff
</pre></div>
<p>网络设备断开时，命名排在最前面的脚本是最后执行的，这就保证了该脚本在“ifupdown”之后执行。</p>
<p>最近又配置了一遍这种关机方法，仍然调试了很久，总结原因：</p>
<ul class="simple">
<li>脚本是由 run-parts 执行的，确保输入脚本路径就可以执行脚本（脚本具有可执行权限，并且以 <tt class="docutils literal"><span class="pre">#!/bin/bash</span></tt> 开头），运行 <tt class="docutils literal">/etc/ifplugd/ifplugd.action $interface down</tt> 确保脚本被调用</li>
<li>确保 ifplugd 在监听需要监听的网络接口（可以看到 <tt class="docutils literal">ifplugd <span class="pre">-i</span> $interface $other_args</tt> 进程在后台运行），在 Debian Stretch 中，在 /etc/default/ifplugd 的 <tt class="docutils literal">INTERFACES</tt> 参数中添加需要被监听的网络接口名称，如果该选项设置为 <tt class="docutils literal">auto</tt> 或者 <tt class="docutils literal">all</tt>，则 ifplugd 只会监听名字以 eth 或者 wlan 开头的网络接口（参考 /etc/init.d/ifplugd 脚本）。</li>
</ul>
</div>

    </div>
<nav class="nav sidebar">
    <div class="siteinfo">
        <div class="sitename"><a href="../..">coinfaces</a></div>
        <div class="tagline">Another Side of Life</div>
    </div>

        <a href="../../categories/">categories</a>
        <a href="../..">&larr; Home</a>
</nav><footer class="footer">
    <span>
        &copy; jpli &middot;
        under <a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/">CC-BY-SA 4.0</a>
    </span>
    |
    <span>
        Powered by:
        <a href="http://blog.getpelican.com/">Pelican</a>
    </span>
</footer></body>
</html>